package visualization;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;

import nodes.Connection;
import nodes.Node;
import nodes.NodeContainer;
import drivers.Config;

public class GuessConverter 
{	
	private Config config;
	public GuessConverter(Config config) {
		this.config = config;
	}
	
	/**
	 * Takes a node container and creates a .gdf file listing the nodes and edges contained in the NodeContainer.
	 * 
	 * @param nc			to convert for display. first node to be displayed as white
	 * @param focusNode		node to focus analysis on
	 */
	public void convert(NodeContainer nc, Node focusNode)
	{
		System.out.println(nc);
		
		int count= 0;
		Collection<Node> allNodes = nc.getAllNodes();	// puts all nodes into a collection for iteration
		ArrayList<Connection> allConnections = new ArrayList<Connection>();		// list of connections for printing edges
		
		// outstream for output to file
		PrintWriter outStream;
		try
		{
			FileWriter file = new FileWriter("output.gdf", false);
			outStream = new PrintWriter(file);
		}
		catch (IOException e)
		{
			System.err.println("ERROR OPENING FILE");
			return;
		}	
		// header for .gdf
		outStream.println("nodedef> name,color,strokecolor,label,labelvisible,width,height");
		
		//go though each node in the list
		Connection co;
		boolean found;
		String color ="";
		String label;
		boolean visible;
		for (Node n: allNodes)
		{
			label = "";
			visible = false;
			//things like color depend on the type of node
			switch(n.getType())
			{
				case Node.NODE_TYPE_LEAF: // leaf
					color = config.getColorLeaves();
					// different labels displayed based on parameters
					if (config.getDisplayIPs() == Config.DISPLAY_TYPE_ALL)
					{
						label = n.getIP() + "  "; 
						visible = true;
					}
					if (config.getDisplayNumConn() == Config.DISPLAY_TYPE_ALL)
					{
						label += n.numConnections();
						visible = true;
					}
					break;
					
				case Node.NODE_TYPE_PEER: // peer
					color = config.getColorPeers();
					// different labels displayed based on parameters
					if (config.getDisplayIPs() == Config.DISPLAY_TYPE_ALL)
					{
						label = n.getIP() + "  "; 
						visible = true;
					}
					if (config.getDisplayNumConn() == Config.DISPLAY_TYPE_ALL)
					{
						label += n.numConnections();
						visible = true;
					}
					break;
					
				case Node.NODE_TYPE_ULTRAPEER: // ultrapeer
					color = config.getColorUltrapeers();
					// different labels displayed based on parameters
					if (config.getDisplayIPs() == Config.DISPLAY_TYPE_ALL || config.getDisplayIPs() == Config.DISPLAY_TYPE_ULTRAPEER)
					{
						label = n.getIP() + "  "; 
						visible = true;
					}
					if (config.getDisplayNumConn() == Config.DISPLAY_TYPE_ALL || config.getDisplayNumConn() == Config.DISPLAY_TYPE_ULTRAPEER)
					{
						label += n.numConnections();
						visible = true;
					}
					break;
			}
			// this makes the focus node white
			if (n.equals(focusNode))
				color = config.getColorFocusNode();
			
			// prints the fully compiled node definition
			outStream.println(n.getIP() + "," + color + "," + color + "," + label + "," + visible + ",16" + ",16");	
			
			count++;
			if (count%100 ==0) System.out.println(count);
			
			//creates a unique set of all connections
			for (Node i: n.getConnections())
			{
				found = false;
				co = new Connection(n, i);
				if (nc.containsIP(i.getIP()))		// have to make sure that the node we want to connect to is in the node container to be displayed
				{
					// make sure the connection is not already added
					for (Connection comp: allConnections)	
					{
						if (co.equals(comp)) found = true;
					}
					if (found == false) allConnections.add(co);					
				}

			}	
		}
		
		// edge def for .gdf
		outStream.println("edgedef> node1,node2,color");
		
		//writes connections to file
		for (Connection c: allConnections)
		{
			outStream.println(c + "," + config.getColorEdges());
		}
		
		outStream.close();
	}
}
